import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class TermTest {

    @Test
    public void testValidConstructor() {
        Term term = new Term("apple", 100);
        assertEquals("apple", term.getTerm());
        assertEquals(100, term.getWeight());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithNullTerm() {
        new Term(null, 50);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithNegativeWeight() {
        new Term("apple", -10);
    }

    @Test
    public void testCompareTo() {
        Term t1 = new Term("apple", 100);
        Term t2 = new Term("banana", 200);
        assertTrue(t1.compareTo(t2) < 0);
        assertTrue(t2.compareTo(t1) > 0);
    }

    @Test
    public void testToString() {
        Term t = new Term("apple", 100);
        assertEquals("100\tapple", t.toString());
    }

    @Test
    public void testByPrefixOrder() {
        Term t1 = new Term("apple", 100);
        Term t2 = new Term("apricot", 150);
        assertEquals(0, Term.byPrefixOrder(2).compare(t1, t2));
        assertTrue(Term.byPrefixOrder(3).compare(t1, t2) < 0);
    }

    @Test
    public void testByPrefixOrderWithShortString() {
        Term t1 = new Term("app", 100);
        Term t2 = new Term("apple", 200);
        assertTrue(Term.byPrefixOrder(5).compare(t1, t2) < 0);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testByPrefixOrderNegativeR() {
        Term.byPrefixOrder(-1);
    }

    @Test
    public void testByReverseWeightOrder() {
        Term t1 = new Term("apple", 100);
        Term t2 = new Term("banana", 200);
        assertTrue(Term.byReverseWeightOrder().compare(t1, t2) > 0);
        assertTrue(Term.byReverseWeightOrder().compare(t2, t1) < 0);
    }

    @Test
    public void testSetters() {
        Term t = new Term("apple", 100);
        t.setTerm("banana");
        assertEquals("banana", t.getTerm());
        t.setWeight(300);
        assertEquals(300, t.getWeight());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testSetTermWithNull() {
        Term t = new Term("apple", 100);
        t.setTerm(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testSetWeightWithNegative() {
        Term t = new Term("apple", 100);
        t.setWeight(-50);
    }
}
